package com.atguigu.aspect;

import com.atguigu.entity.Admin;
import com.atguigu.service.AdminService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author:hx
 * @DateTime:2022/10/5 18:15
 * @Description:
 */
@Component
@Aspect
public class LoggerAspect {

    @DubboReference
    private AdminService adminService;

    private Logger logger = LoggerFactory.getLogger(LoggerAspect.class);

    @Around("execution(* com.atguigu.controller.*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        //获取当前登录信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null){
            try {
                joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
        //获取用户名
        String username = authentication.getName();
        if (username == null || "anonymousUser".equals(username)){
            try {
                joinPoint.proceed();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
        //根据用户名获取用户信息
        Admin admin = adminService.getAdminByUsername(username);
        Long adminId = admin.getId();
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String ip = request.getRemoteHost();
        String className = joinPoint.getSignature().getDeclaringTypeName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        StringBuilder params = new StringBuilder();
        for (int i = 0; i < args.length; i++) {
            if (i == args.length - 1) {
                params.append("params" + (i + 1) + ":" + args[i]);
            } else {
                params.append("params" + (i + 1) + ":" + args[i] + ",");
            }
        }
        Long startTime = System.currentTimeMillis();
        try {
            return joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }finally {
            Long endTime = System.currentTimeMillis();
            Long time = endTime - startTime;
            logger.info("用户编号 : " + adminId + " -- 用户名 : " + username + " -- 请求路径 : " + url + " -- 请求方式 : " + method + " -- ip地址 : " + ip + " -- 类名 : " + className + " -- 方法名 : " + methodName + " -- 参数 : " + (params.toString().equals("") ? "无参数" : params) + " -- 运行时长 : " + time + "毫秒");
        }
        return null;
    }
}
